import tkinter as tk
from tkinter import ttk, messagebox
from pynput import keyboard
import threading
import time

class KeyCounterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("键盘按键计数器")
        self.root.geometry("450x450")
        self.root.resizable(False, False)
        
        # 初始化变量
        self.count = 0
        self.milestone_count = 0
        self.target_key = None
        self.is_listening = False
        self.listener = None
        self.milestone_target = 100  # 默认里程碑目标
        
        # 创建GUI组件
        self.create_widgets()
        
        # 设置窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        
    def create_widgets(self):
        # 标题
        title_label = tk.Label(self.root, text="键盘按键计数器", 
                              font=("微软雅黑", 16, "bold"))
        title_label.pack(pady=10)
        
        # 选择按键框架
        key_frame = tk.Frame(self.root)
        key_frame.pack(pady=10)
        
        tk.Label(key_frame, text="选择要计数的按键：", 
                font=("微软雅黑", 10)).pack(side=tk.LEFT, padx=5)
        
        # 按键选择下拉菜单
        self.key_var = tk.StringVar()
        self.key_combo = ttk.Combobox(key_frame, textvariable=self.key_var, 
                                     width=10, state="readonly")
        self.key_combo['values'] = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
                                   'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
                                   'U', 'V', 'W', 'X', 'Y', 'Z', 'Space', 'Enter', 
                                   'Tab', 'Shift', 'Ctrl', 'Alt')
        self.key_combo.pack(side=tk.LEFT, padx=5)
        self.key_combo.set('A')
        
        # 里程碑设置框架
        milestone_frame = tk.Frame(self.root)
        milestone_frame.pack(pady=10)
        
        tk.Label(milestone_frame, text="里程碑目标：", 
                font=("微软雅黑", 10)).pack(side=tk.LEFT, padx=5)
        
        self.milestone_var = tk.StringVar(value="100")
        self.milestone_entry = tk.Entry(milestone_frame, textvariable=self.milestone_var, 
                                       width=8, font=("微软雅黑", 10))
        self.milestone_entry.pack(side=tk.LEFT, padx=5)
        
        # 计数显示框架
        count_frame = tk.Frame(self.root)
        count_frame.pack(pady=15)
        
        tk.Label(count_frame, text="当前计数：", 
                font=("微软雅黑", 12)).pack(side=tk.LEFT, padx=5)
        
        self.count_label = tk.Label(count_frame, text="0", 
                                   font=("微软雅黑", 24, "bold"), 
                                   fg="blue", bg="white", 
                                   width=10, relief=tk.SUNKEN)
        self.count_label.pack(side=tk.LEFT, padx=5)
        
        # 里程碑计数显示
        milestone_count_frame = tk.Frame(self.root)
        milestone_count_frame.pack(pady=5)
        
        tk.Label(milestone_count_frame, text="里程碑达成：", 
                font=("微软雅黑", 10)).pack(side=tk.LEFT, padx=5)
        
        self.milestone_count_label = tk.Label(milestone_count_frame, text="0", 
                                             font=("微软雅黑", 16, "bold"), 
                                             fg="purple", bg="lightyellow", 
                                             width=8, relief=tk.SUNKEN)
        self.milestone_count_label.pack(side=tk.LEFT, padx=5)
        
        # 进度条框架
        progress_frame = tk.Frame(self.root)
        progress_frame.pack(pady=10, fill=tk.X, padx=20)
        
        tk.Label(progress_frame, text="进度：", 
                font=("微软雅黑", 10)).pack(anchor=tk.W)
        
        self.progress_bar = ttk.Progressbar(progress_frame, length=350, 
                                           mode='determinate', maximum=100)
        self.progress_bar.pack(fill=tk.X, pady=2)
        
        self.progress_label = tk.Label(progress_frame, text="0 / 100", 
                                      font=("微软雅黑", 9), fg="gray")
        self.progress_label.pack(anchor=tk.E)
        
        # 按键状态显示
        self.status_label = tk.Label(self.root, text="状态：未开始", 
                                    font=("微软雅黑", 10), fg="gray")
        self.status_label.pack(pady=5)
        
        # 按钮框架
        button_frame = tk.Frame(self.root)
        button_frame.pack(pady=15, fill=tk.X, padx=20)
        
        # 开始/停止按钮
        self.start_button = tk.Button(button_frame, text="开始监听", 
                                     command=self.toggle_listening,
                                     bg="green", fg="white", 
                                     font=("微软雅黑", 10, "bold"),
                                     width=12)
        self.start_button.pack(side=tk.LEFT, padx=5)
        print("Start button created")  # Debug line
        
        # 重置按钮
        self.reset_button = tk.Button(button_frame, text="重置计数", 
                                     command=self.reset_count,
                                     bg="orange", fg="white", 
                                     font=("微软雅黑", 10, "bold"),
                                     width=12)
        self.reset_button.pack(side=tk.LEFT, padx=5)
        print("Reset button created")  # Debug line
        
        # 说明文字
        info_text = "说明：选择要计数的按键，设置里程碑目标，\n点击'开始监听'后，程序会记录该按键被按下的次数。\n达到里程碑时会有特殊效果！"
        info_label = tk.Label(self.root, text=info_text, 
                             font=("微软雅黑", 9), fg="gray")
        info_label.pack(pady=10)
        
    def on_press(self, key):
        """键盘按下事件处理"""
        try:
            # 获取按下的键
            if hasattr(key, 'char'):
                pressed_key = key.char.upper()
            else:
                # 处理特殊键
                key_map = {
                    keyboard.Key.space: 'Space',
                    keyboard.Key.enter: 'Enter',
                    keyboard.Key.tab: 'Tab',
                    keyboard.Key.shift: 'Shift',
                    keyboard.Key.ctrl: 'Ctrl',
                    keyboard.Key.alt: 'Alt'
                }
                pressed_key = key_map.get(key, None)
            
            # 检查是否是目标键
            if pressed_key == self.target_key:
                self.count += 1
                self.root.after(0, self.update_count_display)
                
                # 检查是否达到里程碑
                if self.count >= self.milestone_target:
                    self.root.after(0, self.celebrate_milestone)
                
        except Exception as e:
            print(f"错误：{e}")
    
    def update_count_display(self):
        """更新计数显示"""
        self.count_label.config(text=str(self.count))
        # 添加一个短暂的视觉反馈
        self.count_label.config(bg="lightgreen")
        self.root.after(100, lambda: self.count_label.config(bg="white"))
        
        # 更新进度条
        self.update_progress()
    
    def update_progress(self):
        """更新进度条"""
        try:
            milestone_target = int(self.milestone_var.get())
            if milestone_target > 0:
                progress = min((self.count / milestone_target) * 100, 100)
                self.progress_bar['value'] = progress
                self.progress_label.config(text=f"{self.count} / {milestone_target}")
        except ValueError:
            pass
    
    def celebrate_milestone(self):
        """庆祝里程碑达成"""
        # 增加里程碑计数
        self.milestone_count += 1
        self.milestone_count_label.config(text=str(self.milestone_count))
        
        # 重置当前计数
        self.count = 0
        self.count_label.config(text="0")
        
        # 特殊视觉效果
        self.create_celebration_effect()
    
    def create_celebration_effect(self):
        """创建庆祝效果"""
        # 创建庆祝标签（不阻塞用户交互）
        celebration_label = tk.Label(self.root, 
                                   text=f"🎉 第{self.milestone_count}个里程碑达成！ 🎉",
                                   font=("微软雅黑", 18, "bold"),
                                   bg="gold", fg="purple",
                                   relief=tk.RAISED, bd=3)
        
        # 将庆祝标签放置在窗口中央
        celebration_label.place(relx=0.5, rely=0.4, anchor=tk.CENTER)
        
        # 3秒后自动移除庆祝标签
        self.root.after(3000, celebration_label.destroy)
        
        # 主窗口闪烁效果
        self.flash_window()
    
    def flash_window(self):
        """窗口闪烁效果"""
        original_bg = self.root.cget("bg")
        colors = ["gold", "lightblue", "lightgreen", "pink", "lightyellow"]
        
        def flash(count=0):
            if count < 6:  # 闪烁3次（6个颜色变化）
                color = colors[count % len(colors)]
                self.root.configure(bg=color)
                self.root.after(200, lambda: flash(count + 1))
            else:
                self.root.configure(bg=original_bg)
        
        flash()
    
    def toggle_listening(self):
        """切换监听状态"""
        if not self.is_listening:
            # 开始监听
            self.target_key = self.key_var.get()
            if not self.target_key:
                messagebox.showwarning("警告", "请先选择要计数的按键！")
                return
            
            # 验证里程碑目标
            try:
                milestone = int(self.milestone_var.get())
                if milestone <= 0:
                    messagebox.showwarning("警告", "里程碑目标必须大于0！")
                    return
                self.milestone_target = milestone
            except ValueError:
                messagebox.showwarning("警告", "请输入有效的里程碑目标数字！")
                return
            
            self.is_listening = True
            self.start_button.config(text="停止监听", bg="red")
            self.status_label.config(text=f"状态：正在监听 '{self.target_key}' 键", fg="green")
            self.key_combo.config(state="disabled")
            self.milestone_entry.config(state="disabled")
            
            # 启动键盘监听器
            self.listener = keyboard.Listener(on_press=self.on_press)
            self.listener.start()
            
        else:
            # 停止监听
            self.is_listening = False
            self.start_button.config(text="开始监听", bg="green")
            self.status_label.config(text="状态：已停止", fg="gray")
            self.key_combo.config(state="readonly")
            self.milestone_entry.config(state="normal")
            
            # 停止监听器
            if self.listener:
                self.listener.stop()
                self.listener = None
    
    def reset_count(self):
        """重置计数"""
        self.count = 0
        self.count_label.config(text="0")
        self.milestone_count = 0
        self.milestone_count_label.config(text="0")
        self.progress_bar['value'] = 0
        self.progress_label.config(text="0 / 100")
        # 添加重置的视觉反馈
        self.count_label.config(bg="yellow")
        self.root.after(200, lambda: self.count_label.config(bg="white"))
    
    def on_closing(self):
        """窗口关闭事件处理"""
        if self.is_listening:
            if self.listener:
                self.listener.stop()
        self.root.destroy()

def main():
    # 创建主窗口
    root = tk.Tk()
    
    # 设置窗口图标（可选）
    try:
        root.iconbitmap(default='')  # 可以添加图标文件路径
    except:
        pass
    
    # 创建应用实例
    app = KeyCounterApp(root)
    
    # 运行主循环
    root.mainloop()

if __name__ == "__main__":
    main()
